import {
    def
} from "./utils";

// 得到Arrau.prototype
const arrayPrototype = Array.prototype;
/* 以Array.prototype 为原型创建arrayMethods 对象, 并暴露（含有7个自己重写的修改数组的方法） */
export const arrayMethods = Object.create(arrayPrototype)

// 要被改写的7个数组方法
const methodsNeedChange = [
    'push',
    'pop',
    'unshift',
    'shift',
    'splice',
    'sort',
    'reverse',
]

methodsNeedChange.forEach(methodName => {
    // 备份原来的方法
    const original = arrayPrototype[methodName]

    // 在根据原型创造的对象中定义自己新的方法
    def(arrayMethods, methodName, function() {
        const result = original.apply(this, arguments)

        // 把这个数组身上的__ob__取出来，__ob__已经被添加了，为什么被添加了？因为数组肯定不是最高层，比如obj.g属性是数组，obj不能是数组了，第一次遍历obj这个对象的第一层的时候，已经给g这个属性（就是这个数组）添加了__ob__这个属性
        const ob = this.__ob__
        
        // arguments 是一个类数组，没有数组方法
        const args = [...arguments]

        // 有三种方法 push\unshift\splice 能够插入新项，现在要把插入的新项也要变为observe的
        let inserted = []

        switch (methodName) {
            case 'push':
            case 'unshift':
                inserted = args;
                break;
            case 'splice':
                // splice 格式（下标，数量，插入新的项）
                inserted = args.slice(2);
                break;
        }
        if (inserted) {
            ob.observeArray(inserted)
        }

        ob.dep.notify()
        console.log('d调用数组的方法：', methodName)

        return result
    }, false)

})